package dynamic.toolkit.support;

import com.github.yulichang.toolkit.FieldStringMap;
import dynamic.config.DConfigProperties;
import dynamic.metadata.DTableInfo;
import dynamic.metadata.EntityClass;
import dynamic.metadata.EntityProperty;
import dynamic.mybatisplus.core.toolkit.DAsserts;
import dynamic.mybatisplus.core.toolkit.DTableHelper;
import dynamic.wrapper.segments.DSelectCache;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.stream.Collectors;

public class DColumnCache {
    private static final Map<EntityClass, List<DSelectCache>> LIST_CACHE = new ConcurrentHashMap<>();

    private static final Map<EntityClass, FieldStringMap<DSelectCache>> MAP_CACHE = new ConcurrentHashMap<>();

    public static List<DSelectCache> getListField(EntityClass clazz) {
        return LIST_CACHE.computeIfAbsent(clazz, c -> {
            DTableInfo tableInfo = DTableHelper.get(clazz);
            DAsserts.hasTable(tableInfo, c);
            List<DSelectCache> list = new ArrayList<>();
            if (DConfigProperties.tableInfoAdapter.mpjHasPK(tableInfo)) {
                list.add(new DSelectCache(clazz, true, tableInfo.getKeyColumn(), tableInfo.getKeyType(),
                        tableInfo.getKeyProperty(), null));
            }
            list.addAll(tableInfo.getFieldList().stream().map(f -> new DSelectCache(clazz, false, f.getColumn(),
                    f.getPropertyType(), f.getProperty(), f)).collect(Collectors.toList()));
            return list;
        });
    }

    public static Map<String, DSelectCache> getMapField(EntityClass clazz) {
        return MAP_CACHE.computeIfAbsent(clazz, c -> getListField(c).stream().collect(Collectors.toMap(
                i -> i.getColumProperty().toUpperCase(Locale.ENGLISH),
                Function.identity(), (i, j) -> j, FieldStringMap::new)));
    }

    public static String getName(String name){
        return name.toUpperCase(Locale.ENGLISH);
    }

    public static String getName(EntityProperty entityProperty){
        return entityProperty.getPropertyName().toUpperCase(Locale.ENGLISH);
    }

    public static String getSqlName(EntityProperty entityProperty){
        String name = entityProperty.getPropertyName();
        if (name.length() == 1 || name.length() > 1 && !Character.isUpperCase(name.charAt(1))) {
            name = name.substring(0, 1).toLowerCase(Locale.ENGLISH) + name.substring(1);
        }
        return name;
    }
}
